package es.tikitaka.actions.competicion;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.End;
import org.jboss.seam.annotations.FlushModeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.datamodel.DataModel;
import org.jboss.seam.faces.FacesMessages;

import es.tikitaka.dao.AmonestacionService;
import es.tikitaka.dao.EstColegiadoService;
import es.tikitaka.dao.EstEquipoService;
import es.tikitaka.dao.EstJugadorService;
import es.tikitaka.dao.GolService;
import es.tikitaka.dao.PartidoLService;
import es.tikitaka.dao.PenaltyService;
import es.tikitaka.dao.SegColegiadoService;
import es.tikitaka.dao.SegEquipoService;
import es.tikitaka.dao.SegJugadorService;
import es.tikitaka.dao.TipoAmonestacionDicService;
import es.tikitaka.dao.TipoGolDicService;
import es.tikitaka.dictionary.TipoAmonestacionDic;
import es.tikitaka.dictionary.TipoGolDic;
import es.tikitaka.domain.Amonestacion;
import es.tikitaka.domain.Estadisticas;
import es.tikitaka.domain.Gol;
import es.tikitaka.domain.Penalty;
import es.tikitaka.domain.Temporada;
import es.tikitaka.domain.colegiado.EstColegiado;
import es.tikitaka.domain.colegiado.SegColegiado;
import es.tikitaka.domain.equipo.EstEquipo;
import es.tikitaka.domain.equipo.SegEquipo;
import es.tikitaka.domain.jugador.EstJugador;
import es.tikitaka.domain.jugador.SegJugador;
import es.tikitaka.domain.liga.PartidoL;

/**
 * 
 * @author Saúl Domínguez
 * @since 2010
 * @category PFC
 */

@Name("partidosAction")
@Scope(ScopeType.CONVERSATION)
public class PartidosAction {

	private PartidoL partido;
	private Temporada temporada;
	private int jornada;

	private List<SegEquipo> equipos;
	@DataModel("locales")
	private List<SegJugador> locales;
	@DataModel("visitantes")
	private List<SegJugador> visitantes;

	private boolean panelGol = false;
	private boolean panelFalta = false;
	private boolean panelPenalty = false;
	private boolean panelLesion = false;

	private Gol gol;
	private StringBuffer goles;
	private Amonestacion amonestacion;
	private SegJugador lesionado;
	private StringBuffer tarjetas;
	private List<SegJugador> jugadores;
	private Penalty penalty;
	private String equipoInfractor;
	private List<SegJugador> infractores;
	private List<SegJugador> lanzadores;

	private List<TipoGolDic> tiposGol;
	private List<TipoAmonestacionDic> tiposAmonestacion;

	@In(create = true)
	private PartidoLService partidoLService;

	@In(create = true)
	private TipoGolDicService tipoGolService;

	@In(create = true)
	private TipoAmonestacionDicService tipoAmonestacionService;

	@In(create = true)
	private AmonestacionService amonestacionService;

	@In(create = true)
	private GolService golService;

	@In(create = true)
	private PenaltyService penaltyService;

	@In(create = true)
	private SegJugadorService segJugadorService;

	@In(create = true)
	private SegEquipoService segEquipoService;

	@In(create = true)
	private SegColegiadoService segColegiadoService;

	/**
	 * Constructor por defecto
	 */
	public PartidosAction() {
	}

	/**
	 * Método para cargar las opciones del partido seleccionado
	 * 
	 * @param par
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void selectPartido(PartidoL par) {
		if (par != null) {
			partido = par;
			equipos = new ArrayList<SegEquipo>();
			equipos.addAll(partido.getM_equipos());
			for (SegEquipo eq : equipos) {
				if (eq.getPartEquipo().getEquipo().getNombre().equals(
						partido.getLocal())) {
					locales = new ArrayList<SegJugador>();
					locales.addAll(eq.getM_jugadores());
					Collections.sort(locales);
				} else {
					visitantes = new ArrayList<SegJugador>();
					visitantes.addAll(eq.getM_jugadores());
					Collections.sort(visitantes);
				}
			}
			temporada = partido.getColegiado().getPartColegiado()
					.getTemporada();
			jornada = partido.getJornada().getNumJor();
		}
	}

	/**
	 * Método para añadir un nuevo gol al partido
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void addGol(String equipo) {
		panelGol = true;
		// se cargan las opciones de tipos de goles
		tiposGol = tipoGolService.getList();
		// se crea un gol y se le asigna el partido en cuestion
		gol = new Gol();
		gol.setPartido(partido);
		// se cargan los jugadores que han podido meter el gol
		jugadores = new ArrayList<SegJugador>();
		if (equipo.equals("local")) {
			for (SegJugador jug : locales) {
				if (jug.isJuega() && !jug.isLesionado()) {
					jugadores.add(jug);
				}
			}
		} else {
			for (SegJugador jug : visitantes) {
				if (jug.isJuega() && !jug.isLesionado()) {
					jugadores.add(jug);
				}
			}
		}
	}

	/**
	 * Método para cancelar un nuevo gol
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void cancelGol() {
		panelGol = false;
		gol = null;
	}

	/**
	 * Método para confirmar un nuevo gol en el partido
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public boolean confirmGol() {
		boolean permiso = true;

		if (gol.getMinuto() <= 0 || gol.getMinuto() > 20) {
			permiso = false;
			FacesMessages
					.instance()
					.add(
							"Está intentando confirmar un gol que no está dentro del tiempo");
		}
		if (permiso) {
			// comprobamos que existe un conjunto de goles para el partido, si
			// no,
			// lo creamos
			if (partido.getM_goles() == null) {
				// no existe
				partido.setM_goles(new HashSet<Gol>());
			} else {
				// existe un conjunto de goles. Hay que comporbar que el gol que
				// se
				// está confirmando está dentro de los márgenes de tiempo
				List<Gol> goals = new ArrayList<Gol>();
				goals.addAll(partido.getM_goles());
				// Ordenamos los goles
				Collections.sort(goals);
				if (goals.size() > 0) {
					Gol g = goals.get(goals.size() - 1);
					if (g.getPeriodo() > gol.getPeriodo()) {
						permiso = false;
						FacesMessages
								.instance()
								.add(
										"Está intentando confirmar un gol que no está dentro del tiempo");
					} else if (g.getPeriodo() == gol.getPeriodo()) {
						if (g.getMinuto() > gol.getMinuto()) {
							permiso = false;
							FacesMessages
									.instance()
									.add(
											"Está intentando confirmar un gol que no está dentro del tiempo");
						}
					}
				}
			}
			if (permiso) {
				// comprobamos si hay goles o no
				if (goles == null) {
					goles = new StringBuffer();
				}
				// añadimos el gol al partido
				partido.getM_goles().add(gol);
				// subimos el gol al marcador del equipo
				if (locales.contains(gol.getJugador())) {
					int golL = partido.getGolesL();
					golL++;
					partido.setGolesL(golL);
				} else {
					int golV = partido.getGolesV();
					golV++;
					partido.setGolesV(golV);
				}
				// rellenamos incidencias
				goles.append(partido.getGolesL());
				goles.append("-");
				goles.append(partido.getGolesV());
				goles.append(": ");
				goles.append(gol.getPeriodo());
				goles.append("ª parte, ");
				goles.append("min ");
				goles.append(gol.getMinuto());
				goles.append(". ");
				goles.append(gol.getJugador().getPartJugador().getJugador()
						.getNombre());
				if (gol.getTipoGol().getTipo().equals("Gol penalty")) {
					goles.append("(p)");
				}
				goles.append("; ");

				// inicializamos variables
				panelGol = false;
				gol = null;
			}
		}
		return permiso;
	}

	/**
	 * Método para ver el número de goles de un jugador y así mostrarlo en
	 * pantalla
	 * 
	 * @param jug
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public String verGoles(SegJugador jug) {
		StringBuffer url = new StringBuffer();
		int num = 0;
		if (partido.getM_goles() != null && partido.getM_goles().size() > 0) {
			for (Gol g : partido.getM_goles()) {
				if (g.getJugador().equals(jug)) {
					num++;
				}
			}
		}
		if (num != 0 && num < 11) {
			url.append("/temas/tiki/imagenes/iconitos/Gol");
			url.append(num);
			url.append(".png");
		}
		return url.toString();
	}

	/**
	 * Método para añadir una nueva falta
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void addFalta(String equipo) {
		panelFalta = true;
		// se cargan las opciones de tipos de amonestación
		tiposAmonestacion = tipoAmonestacionService.getList();
		// se crea una amonestacion y se le asigna el partido en cuestion
		amonestacion = new Amonestacion();
		amonestacion.setPartido(partido);
		// se cargan los jugadoresque han podidio cometer la falta
		jugadores = new ArrayList<SegJugador>();
		if (equipo.equals("local")) {
			for (SegJugador jug : locales) {
				if (jug.isJuega() && !jug.isLesionado()) {
					jugadores.add(jug);
				}
			}
		} else {
			for (SegJugador jug : visitantes) {
				if (jug.isJuega() && !jug.isLesionado()) {
					jugadores.add(jug);
				}
			}
		}
	}

	/**
	 * Método para cancelar una nueva falta
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void cancelFalta() {
		panelFalta = false;
		amonestacion = null;
	}

	/**
	 * Método para confirmar una nueva falta en el partido
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public boolean confirmFalta() {
		boolean permiso = true;
		if (amonestacion != null) {
			if (amonestacion.getMin() <= 0 || amonestacion.getMin() > 20) {
				permiso = false;
				FacesMessages
						.instance()
						.add(
								"Está intentando confirmar un amonestación que no está dentro del tiempo");
			}
		}
		if (permiso) {
			// comprobamos que existe un conjunto de amonestaciones para el
			// partido,
			// si no,
			// lo creamos
			if (partido.getM_amonestaciones() == null) {
				partido.setM_amonestaciones(new HashSet<Amonestacion>());
			} else {
				// existe un conjunto de amonestaciones. Hay que comporbar que
				// la amonestación que
				// se está confirmando está dentro de los márgenes de tiempo
				List<Amonestacion> amons = new ArrayList<Amonestacion>();
				amons.addAll(partido.getM_amonestaciones());
				// Ordenamos las amonestaciones
				Collections.sort(amons);
				if (amons.size() > 0) {
					Amonestacion a = amons.get(amons.size() - 1);
					if (a.getPeriodo() > amonestacion.getPeriodo()) {
						permiso = false;
						FacesMessages
								.instance()
								.add(
										"Esta intentando confirmar una amonestación que no tiene un tiempo correcto");
					} else if (a.getPeriodo() == amonestacion.getPeriodo()) {
						if (a.getMin() > amonestacion.getMin()) {
							permiso = false;
							FacesMessages
									.instance()
									.add(
											"Está intentando confirmar una amonestación que no tiene un tiempo correcto");
						}
					}
				}
			}
		}
		if (permiso) {
			// comprobamos si hay amonestaciones o no
			if (tarjetas == null) {
				tarjetas = new StringBuffer();
			}
			// añadimos la amonestación al partido
			partido.getM_amonestaciones().add(amonestacion);
			// subimos la amonestación al marcador del equipo
			if (locales.contains(amonestacion.getJugador())) {
				int faltasL = partido.getFaltasL();
				faltasL++;
				partido.setFaltasL(faltasL);
			} else {
				int faltasV = partido.getFaltasV();
				faltasV++;
				partido.setFaltasV(faltasV);
			}
			// rellenamos incidencias
			if (amonestacion.getTipo() != null) {
				tarjetas.append(amonestacion.getPeriodo());
				tarjetas.append("ª parte, ");
				tarjetas.append("min ");
				tarjetas.append(amonestacion.getMin());
				tarjetas.append(". ");
				tarjetas.append(amonestacion.getTipo().getTipo());
				tarjetas.append(" a ");
				tarjetas.append(amonestacion.getJugador().getPartJugador()
						.getJugador().getNombre());
				tarjetas.append("; ");
			}
			// inicializamos variables
			panelFalta = false;
			amonestacion = null;
		}
		return permiso;
	}

	/**
	 * Método para ver el número de faltas de un jugador
	 * 
	 * @param jug
	 * @return
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public String verFaltasJug(SegJugador jug) {
		// TODO Cambiar goles por faltas
		StringBuffer url = new StringBuffer();
		int num = 0;
		if (partido.getM_amonestaciones() != null
				&& partido.getM_amonestaciones().size() > 0) {
			for (Amonestacion a : partido.getM_amonestaciones()) {
				if (a.getJugador().equals(jug)) {
					num++;
				}
			}
		}
		if (num != 0 && num < 11) {
			url.append("/temas/tiki/imagenes/iconitos/falta");
			url.append(num);
			url.append("jug.png");
		}
		return url.toString();
	}

	/**
	 * Método para ver las tarjetas que tiene un jugador
	 * 
	 * @param jug
	 * @return
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public String verTarjetas(SegJugador jug) {
		StringBuffer url = new StringBuffer();
		TipoAmonestacionDic ta = null;
		TipoAmonestacionDic tr = null;
		TipoAmonestacionDic taz = null;
		int numta = 0;
		if (partido.getM_amonestaciones() != null
				&& partido.getM_amonestaciones().size() > 0) {
			for (Amonestacion a : partido.getM_amonestaciones()) {
				if (a.getTipo() != null) {
					if (a.getJugador().equals(jug)) {
						if (a.getTipo().getTipo().equals("Tarjeta amarilla")) {
							ta = new TipoAmonestacionDic();
							ta = a.getTipo();
							numta++;
						} else if (a.getTipo().getTipo().equals("Tarjeta roja")) {
							tr = new TipoAmonestacionDic();
							tr = a.getTipo();
						} else if (a.getTipo().getTipo().equals("Tarjeta azul")) {
							taz = new TipoAmonestacionDic();
							taz = a.getTipo();
						}
					}
				}
			}
		}
		if (ta != null && numta == 1 && tr == null && taz == null) {
			// sólo tiene una tarjeta amarilla
			url.append("/temas/tiki/imagenes/iconitos/tarjetaAmarilla.png");
		} else if (ta != null && numta == 2 && tr == null && taz == null) {
			// tiene doble tarjeta amarilla
			url
					.append("/temas/tiki/imagenes/iconitos/tarjetaAmarillaDoble.png");
		} else if (ta == null && tr != null && taz == null) {
			// tiene tarjeta roja
			url.append("/temas/tiki/imagenes/iconitos/tarjetaRoja.png");
		} else if (ta == null && tr == null && taz != null) {
			// tiene tarjeta azul
			url.append("/temas/tiki/imagenes/iconitos/tarjetaAzul.png");
		} else if (ta != null && numta == 1 && tr != null && taz == null) {
			// tiene una amarilla y una roja
			url
					.append("/temas/tiki/imagenes/iconitos/tarjetaAmarillaYRoja.png");
		} else if (ta != null && numta == 2 && tr != null && taz == null) {
			// tiene doble amarilla y una roja
			url
					.append("/temas/tiki/imagenes/iconitos/tarjetaDobleAmarillaYRoja.png");
		} else if (ta != null && numta == 1 && tr == null && taz != null) {
			// tiene una amarilla y una azul
			url
					.append("/temas/tiki/imagenes/iconitos/tarjetaAmarillaYAzul.png");
		} else if (ta != null && numta == 2 && tr == null && taz != null) {
			// tiene doble amarilla y una azul
			url
					.append("/temas/tiki/imagenes/iconitos/tarjetaDobleAmarillaYAzul.png");
		}
		return url.toString();
	}

	/**
	 * Método para ver el número de faltas del equipo local
	 * 
	 * @return
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public String verFaltasLocales() {
		StringBuffer url = new StringBuffer();
		url.append("/temas/tiki/imagenes/iconitos/falta");
		url.append(partido.getFaltasL());
		url.append(".png");
		return url.toString();
	}

	/**
	 * Método para ver el número de faltas del equipo visitante
	 * 
	 * @return
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public String verFaltasVisitantes() {
		StringBuffer url = new StringBuffer();
		url.append("/temas/tiki/imagenes/iconitos/falta");
		url.append(partido.getFaltasV());
		url.append(".png");
		return url.toString();
	}

	/**
	 * Método para añadir un nuevo penalty
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void addPenalty() {
		panelPenalty = true;
		// se crea un penalty y se le asigna el partido
		penalty = new Penalty();
		penalty.setPartido(partido);
		amonestacion = new Amonestacion();
		amonestacion.setPartido(partido);
		// se cargan las opciones de tipos de amonestación
		tiposAmonestacion = tipoAmonestacionService.getList();
	}

	/**
	 * Método para cancelar un nuevo penalty
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void cancelPenalty() {
		panelPenalty = false;
		penalty = null;
		amonestacion = null;
	}

	/**
	 * Método para confirmar un nuevo penalty en el partido
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void confirmPenalty() {
		// comprobamos que hay un infractor y un lanzador del penalty
		if (penalty.getLanzador() != null && penalty.getInfractor() != null) {
			// comprobamos si el penalty ha sido gol o no
			if (penalty.isGol()) {
				gol = new Gol();
				TipoGolDic tipoGol = new TipoGolDic();
				tipoGol = tipoGolService.getTipo("penalty");
				gol.setPartido(partido);
				gol.setJugador(penalty.getLanzador());
				gol.setPeriodo(penalty.getPeriodo());
				gol.setMinuto(penalty.getMin());
				gol.setTipoGol(tipoGol);
				if (confirmGol()) {
					panelPenalty = false;
				}
			}
			if (amonestacion != null && amonestacion.getTipo() != null) {
				amonestacion.setPartido(partido);
				amonestacion.setJugador(penalty.getInfractor());
				amonestacion.setPeriodo(penalty.getPeriodo());
				amonestacion.setMin(penalty.getMin());
				if (confirmFalta()) {
					panelPenalty = false;
				}
			}
		}
	}

	/**
	 * Método para cargar los datos de jugadres para seleccionar el infractor y
	 * el lanzador del penalty
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void cargaJugadoresPenalty() {
		infractores = new ArrayList<SegJugador>();
		lanzadores = new ArrayList<SegJugador>();
		if (equipoInfractor.equals("local")) {
			for (SegJugador jug : locales) {
				if (jug.isJuega() && !jug.isLesionado()) {
					infractores.add(jug);
				}
			}
			for (SegJugador jug : visitantes) {
				if (jug.isJuega() && !jug.isLesionado()) {
					lanzadores.add(jug);
				}
			}
		} else if (equipoInfractor.equals("visitante")) {
			for (SegJugador jug : visitantes) {
				if (jug.isJuega() && !jug.isLesionado()) {
					infractores.add(jug);
				}
			}
			for (SegJugador jug : locales) {
				if (jug.isJuega() && !jug.isLesionado()) {
					lanzadores.add(jug);
				}
			}
		}
	}

	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void addLesion(String equipo) {
		panelLesion = true;
		lesionado = new SegJugador();
		// se cargan los jugadores que se han podido lesionar
		jugadores = new ArrayList<SegJugador>();
		if (equipo.equals("local")) {
			for (SegJugador jug : locales) {
				if (jug.isJuega() && !jug.isLesionado()) {
					jugadores.add(jug);
				}
			}
		} else {
			for (SegJugador jug : visitantes) {
				if (jug.isJuega() && !jug.isLesionado()) {
					jugadores.add(jug);
				}
			}
		}
	}

	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void cancelLesion() {
		panelLesion = false;
		lesionado = null;
	}

	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void confirmLesion() {
		if (lesionado != null) {
			lesionado.setLesionado(true);
			panelLesion = false;
		}
	}

	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public String verLesion(SegJugador jug) {
		StringBuffer url = new StringBuffer();
		if (jug.isLesionado()) {
			url.append("/temas/tiki/imagenes/iconitos/medical.png");
		}
		return url.toString();
	}

	/**
	 * Método para comprobar los datos del partido de un jugador para el caso en
	 * que deje de jugar y tenga datos
	 * 
	 * @param jug
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void comprobarDatos(SegJugador jug) {
		if (jug != null) {
			if (partido.getM_goles() != null) {
				for (Gol g : partido.getM_goles()) {
					if (g.getJugador().equals(jug)) {
						FacesMessages
								.instance()
								.add(
										"El jugador no puede dejar de jugar ya que hay goles suyos en el partido");
						jug.setJuega(true);
					}
				}
			}
			if (partido.getM_amonestaciones() != null) {
				for (Amonestacion a : partido.getM_amonestaciones()) {
					if (a.getJugador().equals(jug)) {
						FacesMessages
								.instance()
								.add(
										"El jugador no puede dejar de jugar ya que hay amonestaciones suyas en el partido");
						jug.setJuega(true);
					}
				}
			}
			if (partido.getM_penaltys() != null) {
				for (Penalty p : partido.getM_penaltys()) {
					if (p.getInfractor().equals(jug)) {
						FacesMessages
								.instance()
								.add(
										"El jugador no puede dejar de jugar ya que ha cometido penaltis en el partido");
						jug.setJuega(true);
					} else if (p.getLanzador().equals(jug)) {
						FacesMessages
								.instance()
								.add(
										"El jugador no puede dejar de jugar ya que hay lanzado penaltis en el partido");
						jug.setJuega(true);
					}
				}
			}
		}
	}

	/**
	 * Método para guardar los datos de un partido
	 */
	public void guardar() {
		// Se comprueba que juegan cinco jugadores por equipo
		List<SegJugador> eqLocal = new ArrayList<SegJugador>();
		List<SegJugador> eqVisitante = new ArrayList<SegJugador>();
		Iterator it = partido.getM_equipos().iterator();
		while (it.hasNext()) {
			SegEquipo e = (SegEquipo) it.next();
			if (e.getPartEquipo().getEquipo().getNombre().equals(
					partido.getLocal())) {
				for (SegJugador jug : e.getM_jugadores()) {
					if (jug.isJuega()) {
						eqLocal.add(jug);
					}
				}
			} else {
				for (SegJugador jug : e.getM_jugadores()) {
					if (jug.isJuega()) {
						eqVisitante.add(jug);
					}
				}
			}
		}
		if (eqLocal.size() > 4 && eqVisitante.size() > 4) {
			// numero de jugadores por equipo correcto
			if (partido.getM_amonestaciones() != null
					&& partido.getM_amonestaciones().size() > 0) {
				for (Amonestacion a : partido.getM_amonestaciones()) {
					amonestacionService.save(a);
				}
			}
			if (partido.getM_goles() != null && partido.getM_goles().size() > 0) {
				for (Gol g : partido.getM_goles()) {
					golService.save(g);
				}
			}
			if (partido.getM_penaltys() != null
					&& partido.getM_penaltys().size() > 0) {
				for (Penalty p : partido.getM_penaltys()) {
					penaltyService.save(p);
				}
			}
			if (!partido.isFin()) {
				partido.setEstado("en juego");
			} else {
				partido.setEstado("finalizado");
			}
			partidoLService.save(partido);
		} else {
			FacesMessages
					.instance()
					.add(
							"Hay equipos que no tienen el número mínimo de jugadores jugando el partido");
		}
	}

	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void finalizar() {
		partido.setFin(true);
		rellenaEstadisticasJugadores();
		rellenaEstadisticasEquipos();
		rellenaEstadisticasColegiado();
		guardar();
	}

	/**
	 * Método para rellenar las estadísticas de los jugadores participantes en
	 * el partido
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	private void rellenaEstadisticasJugadores() {
		for (SegEquipo e : partido.getM_equipos()) {
			// se recorre los jugadores equipo por equipo
			String equipo = "";
			// miramos si el equipo es el local o el visitante
			if (e.getPartEquipo().getEquipo().getNombre().equals(
					partido.getLocal())) {
				equipo = "local";
			} else {
				equipo = "visitante";
			}
			for (SegJugador j : e.getM_jugadores()) {
				// se recorre jugador por jugador para rellenar los datos
				// estadísticos
				EstJugador ej = j.getPartJugador().getEstadisticas();
				if (ej == null) {
					ej = new EstJugador();
					j.getPartJugador().setEstadisticas(ej);
				}
				if (j.isJuega()) {
					// si le jugador juega se aumenta el número de partidos
					// jugados
					j.getPartJugador().getEstadisticas().setPartidosJ(
							ej.getPartidosJ() + 1);
					// vemos el resultado del encuentro para rellenar las
					// estadísticas correctas
					if (equipo.equals("local")) {
						if (partido.getGolesL() > partido.getGolesV()) {
							j.getPartJugador().getEstadisticas().setPartidosG(
									ej.getPartidosG() + 1);
						} else if (partido.getGolesL() < partido.getGolesV()) {
							j.getPartJugador().getEstadisticas().setPartidosP(
									ej.getPartidosP() + 1);
						} else {
							j.getPartJugador().getEstadisticas().setPartidosE(
									ej.getPartidosE() + 1);
						}
					} else {
						if (partido.getGolesL() > partido.getGolesV()) {
							j.getPartJugador().getEstadisticas().setPartidosP(
									ej.getPartidosP() + 1);
						} else if (partido.getGolesL() < partido.getGolesV()) {
							j.getPartJugador().getEstadisticas().setPartidosG(
									ej.getPartidosG() + 1);
						} else {
							j.getPartJugador().getEstadisticas().setPartidosE(
									ej.getPartidosE() + 1);
						}
					}
					// Recorremos los goles del jugador para rellenar las
					// estadísticas de goles
					j.getPartJugador().getEstadisticas().setGoles(
							ej.getGoles() + j.getM_goles().size());
					for (Gol g : j.getM_goles()) {
						if (g.getTipoGol().getTipo().equals("Gol cabeza")) {
							j.getPartJugador().getEstadisticas()
									.setGolesCabeza(ej.getGolesCabeza() + 1);
						} else if (g.getTipoGol().getTipo().equals(
								"Gol balón parado")) {
							j.getPartJugador().getEstadisticas().setGolesBP(
									ej.getGolesBP() + 1);
						} else if (g.getTipoGol().getTipo().equals(
								"Gol pie derecho")
								|| g.getTipoGol().getTipo().equals(
										"Gol pie izquierdo")) {
							j.getPartJugador().getEstadisticas().setGolesPie(
									ej.getGolesPie() + 1);
						} else if (g.getTipoGol().getTipo().equals(
								"Gol penalty")) {
							j.getPartJugador().getEstadisticas().setGolesP(
									ej.getGolesP() + 1);
						}
					}
					// Recorremos las amonestaciones para rellenar las
					// estadísticas de tarjetas
					for (Amonestacion a : j.getM_amonestaciones()) {
						if (a.getTipo() != null) {
							if (a.getTipo().getTipo()
									.equals("Tarjeta amarilla")) {
								j.getPartJugador().getEstadisticas()
										.setAmarillas(ej.getAmarillas() + 1);
							} else if (a.getTipo().getTipo().equals(
									"Tarjeta azul")) {
								j.getPartJugador().getEstadisticas().setAzules(
										ej.getAzules() + 1);
							} else if (a.getTipo().getTipo().equals(
									"Tarjeta roja")) {
								j.getPartJugador().getEstadisticas().setRojas(
										ej.getRojas() + 1);
							}
						}
					}
					// Rellenamos las estadísticas de los penaltis
					j.getPartJugador().getEstadisticas().setPenaltysL(
							ej.getPenaltysL() + j.getM_lanzados().size());
					j.getPartJugador().getEstadisticas().setPenaltysC(
							ej.getPenaltysC() + j.getM_cometidos().size());
					// Guardamos los datos del jugador
					segJugadorService.save(j);
				}
			}
		}
	}

	/**
	 * Método para rellenar las estadísticas de los equipos participantes en el
	 * partido
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	private void rellenaEstadisticasEquipos() {
		for (SegEquipo e : partido.getM_equipos()) {
			// Se recorren los dos equipos
			String equipo = "";
			// miramos si el equipo es el local o el visitante
			if (e.getPartEquipo().getEquipo().getNombre().equals(
					partido.getLocal())) {
				equipo = "local";
			} else {
				equipo = "visitante";
			}
			EstEquipo eq = e.getPartEquipo().getEstadisticas();
			if (eq == null) {
				eq = new EstEquipo();
				e.getPartEquipo().setEstadisticas(eq);
			}
			// sumamos el partido jugado
			e.getPartEquipo().getEstadisticas().setPartidosJ(
					eq.getPartidosJ() + 1);
			if (equipo.equals("local")) {
				// vemos el resultado del partido para rellenar las estadísticas
				// y subir los puntos correspondientes
				if (partido.getGolesL() > partido.getGolesV()) {
					e.getPartEquipo().getEstadisticas().setPartidosG(
							eq.getPartidosG() + 1);
					e.getPartEquipo().getEstadisticas().setPuntos(
							eq.getPuntos() + 3);
				} else if (partido.getGolesL() < partido.getGolesV()) {
					e.getPartEquipo().getEstadisticas().setPartidosP(
							eq.getPartidosP() + 1);
				} else {
					e.getPartEquipo().getEstadisticas().setPartidosE(
							eq.getPartidosE() + 1);
					e.getPartEquipo().getEstadisticas().setPuntos(
							eq.getPuntos() + 1);
				}
				// sumamos las estadísticas del partido (tarjetas, goles...)
				// faltas
				e.getPartEquipo().getEstadisticas().setFaltasC(
						eq.getFaltasC() + partido.getFaltasL());
				e.getPartEquipo().getEstadisticas().setFaltasR(
						eq.getFaltasR() + partido.getFaltasV());
				// goles
				e.getPartEquipo().getEstadisticas().setGolesF(
						eq.getGolesF() + partido.getGolesL());
				e.getPartEquipo().getEstadisticas().setGolesC(
						eq.getGolesC() + partido.getGolesV());
			} else {
				if (partido.getGolesL() > partido.getGolesV()) {
					e.getPartEquipo().getEstadisticas().setPartidosP(
							eq.getPartidosP() + 1);
				} else if (partido.getGolesL() < partido.getGolesV()) {
					e.getPartEquipo().getEstadisticas().setPartidosG(
							eq.getPartidosG() + 1);
					e.getPartEquipo().getEstadisticas().setPuntos(
							eq.getPuntos() + 3);
				} else {
					e.getPartEquipo().getEstadisticas().setPartidosE(
							eq.getPartidosE() + 1);
					e.getPartEquipo().getEstadisticas().setPuntos(
							eq.getPuntos() + 1);
				}
				// sumamos las estadísticas del partido (tarjetas, goles...)
				// faltas
				e.getPartEquipo().getEstadisticas().setFaltasC(
						eq.getFaltasC() + partido.getFaltasV());
				e.getPartEquipo().getEstadisticas().setFaltasR(
						eq.getFaltasR() + partido.getFaltasL());
				// goles
				e.getPartEquipo().getEstadisticas().setGolesF(
						eq.getGolesF() + partido.getGolesV());
				e.getPartEquipo().getEstadisticas().setGolesC(
						eq.getGolesC() + partido.getGolesL());

			}
			// Recorremos los goles para rellenar las estadísticas de goles a
			// balón parado
			for (Gol g : partido.getM_goles()) {
				if (g.getTipoGol().getTipo().equals("Gol balón parado")) {
					if (g.getJugador().getSegEquipo().equals(e)) {
						e.getPartEquipo().getEstadisticas().setGolesFBP(
								eq.getGolesFBP() + 1);
					} else {
						e.getPartEquipo().getEstadisticas().setGolesCBP(
								eq.getGolesCBP() + 1);
					}
				}
			}
			// Recorremos las amonestaciones para rellenar las estadísticas de
			// tarjetas
			for (Amonestacion a : partido.getM_amonestaciones()) {
				if (a.getTipo() != null) {
					if (a.getTipo().getTipo().equals("Tarjeta amarilla")) {
						if (a.getJugador().getSegEquipo().equals(e)) {
							e.getPartEquipo().getEstadisticas().setAmarillas(
									eq.getAmarillas() + 1);
						}
					} else if (a.getTipo().getTipo().equals("Tarjeta azul")) {
						if (a.getJugador().getSegEquipo().equals(e)) {
							e.getPartEquipo().getEstadisticas().setAzules(
									eq.getAzules() + 1);
						}
					} else if (a.getTipo().getTipo().equals("Tarjeta roja")) {
						if (a.getJugador().getSegEquipo().equals(e)) {
							e.getPartEquipo().getEstadisticas().setRojas(
									eq.getRojas() + 1);
						}
					}
				}
			}
			// Recorremos los penaltis para rellenar las estadísticas
			for (Penalty p : partido.getM_penaltys()) {
				if (e.getM_jugadores().contains(p.getInfractor())) {
					// el penalty es cometido por el equipo
					e.getPartEquipo().getEstadisticas().setPenaltysC(
							eq.getPenaltysC() + 1);
				} else {
					// el penalty ha sido lanzado por el equipo
					if (p.isGol()) {
						// ha sido gol
						e.getPartEquipo().getEstadisticas().setPenaltysM(
								eq.getPenaltysM() + 1);
					} else {
						// no ha sido gol
						e.getPartEquipo().getEstadisticas().setPenaltysF(
								eq.getPenaltysF() + 1);
					}
				}
			}
			// Guardamos los datos del equipo
			segEquipoService.save(e);
		}
	}

	/**
	 * Método para rellenar las estadísticas del colegiado
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	private void rellenaEstadisticasColegiado() {
		SegColegiado c = partido.getColegiado();
		EstColegiado ec = partido.getColegiado().getPartColegiado()
				.getEstadisticas();
		if (ec == null) {
			ec = new EstColegiado();
			partido.getColegiado().getPartColegiado().setEstadisticas(ec);
		}
		// partidos arbitrados
		c.getPartColegiado().getEstadisticas()
				.setPartidos(ec.getPartidos() + 1);
		// tarjetas amarillas
		c.getPartColegiado().getEstadisticas().setAmarillas(
				ec.getAmarillas() + partido.getAmarillasL()
						+ partido.getAmarillasV());
		c.getPartColegiado().getEstadisticas().setAmarillasL(
				ec.getAmarillasL() + partido.getAmarillasL());
		c.getPartColegiado().getEstadisticas().setAmarillasV(
				ec.getAmarillasV() + partido.getAmarillasV());
		// tarjetas rojas
		c.getPartColegiado().getEstadisticas().setRojas(
				ec.getRojas() + partido.getRojasL() + partido.getRojasV());
		c.getPartColegiado().getEstadisticas().setRojasL(
				ec.getRojasL() + partido.getRojasL());
		c.getPartColegiado().getEstadisticas().setRojasV(
				ec.getRojasV() + partido.getRojasV());
		// vemos el signo del partido
		if (partido.getGolesL() > partido.getGolesV()) {
			// 1
			c.getPartColegiado().getEstadisticas().setUno(ec.getUno() + 1);
		} else if (partido.getGolesL() < partido.getGolesV()) {
			// 2
			c.getPartColegiado().getEstadisticas().setDos(ec.getDos() + 1);
		} else {
			// x
			c.getPartColegiado().getEstadisticas().setX(ec.getX() + 1);
		}
		// Guardamos los datos del colegiado
		segColegiadoService.save(c);
	}

	/**
	 * Método para inicializar todos los parámetros al volver a la pantalla de
	 * consulta de calendario
	 */
	public void volver() {
		if (!partido.isFin()) {
			partidoLService.merge(partido);
		}
		limpiar();
	}

	/**
	 * Método para inicializar todos los parámetros al volver al menú principal
	 */
	@End
	public void menu() {
		limpiar();
	}

	private void limpiar() {
		partido = null;
		temporada = null;
		panelGol = false;
		panelFalta = false;
		panelPenalty = false;
		gol = null;
		amonestacion = null;
		penalty = null;
		locales = null;
		visitantes = null;
		equipos = null;
	}

	/*
	 * getters and setters
	 */

	/**
	 * 
	 * @return
	 */
	public PartidoL getPartido() {
		return partido;
	}

	/**
	 * 
	 * @param partido
	 */
	public void setPartido(PartidoL partido) {
		this.partido = partido;
	}

	/**
	 * 
	 * @return
	 */
	public Temporada getTemporada() {
		return temporada;
	}

	/**
	 * 
	 * @param temporada
	 */
	public void setTemporada(Temporada temporada) {
		this.temporada = temporada;
	}

	/**
	 * 
	 * @return
	 */
	public int getJornada() {
		return jornada;
	}

	/**
	 * 
	 * @param jornada
	 */
	public void setJornada(int jornada) {
		this.jornada = jornada;
	}

	/**
	 * 
	 * @return
	 */
	public List<SegJugador> getLocales() {
		return locales;
	}

	/**
	 * 
	 * @param locales
	 */
	public void setLocales(List<SegJugador> locales) {
		this.locales = locales;
	}

	/**
	 * 
	 * @return
	 */
	public List<SegJugador> getVisitantes() {
		return visitantes;
	}

	/**
	 * 
	 * @param visitantes
	 */
	public void setVisitantes(List<SegJugador> visitantes) {
		this.visitantes = visitantes;
	}

	/**
	 * 
	 * @return
	 */
	public boolean isPanelGol() {
		return panelGol;
	}

	/**
	 * 
	 * @param gol
	 */
	public void setPanelGol(boolean gol) {
		panelGol = gol;
	}

	/**
	 * 
	 * @return
	 */
	public boolean isPanelFalta() {
		return panelFalta;
	}

	/**
	 * 
	 * @param falta
	 */
	public void setPanelFalta(boolean falta) {
		panelFalta = falta;
	}

	/**
	 * 
	 * @return
	 */
	public boolean isPanelPenalty() {
		return panelPenalty;
	}

	/**
	 * 
	 * @param penalty
	 */
	public void setPanelPenalty(boolean penalty) {
		panelPenalty = penalty;
	}

	/**
	 * 
	 * @return
	 */
	public boolean isPanelLesion() {
		return panelLesion;
	}

	/**
	 * 
	 * @param panelLesion
	 */
	public void setPanelLesion(boolean panelLesion) {
		this.panelLesion = panelLesion;
	}

	/**
	 * 
	 * @return
	 */
	public Gol getGol() {
		return gol;
	}

	/**
	 * 
	 * @param gol
	 */
	public void setGol(Gol gol) {
		this.gol = gol;
	}

	/**
	 * 
	 * @return
	 */
	public StringBuffer getGoles() {
		if (goles == null) {
			goles = new StringBuffer();
			int golesL = 0;
			int golesV = 0;
			List<Gol> golesPartido = new ArrayList<Gol>();
			golesPartido.addAll(partido.getM_goles());
			Collections.sort(golesPartido);
			for (Gol g : golesPartido) {
				if (locales.contains(g.getJugador())) {
					golesL++;
				} else {
					golesV++;
				}
				// rellenamos incidencias
				goles.append(golesL);
				goles.append("-");
				goles.append(golesV);
				goles.append(": ");
				goles.append(g.getPeriodo());
				goles.append("ª parte, ");
				goles.append("min ");
				goles.append(g.getMinuto());
				goles.append(". ");
				goles.append(g.getJugador().getPartJugador().getJugador()
						.getNombre());
				if (g.getTipoGol().getTipo().equals("Gol penalty")) {
					goles.append("(p.)");
				}
				goles.append("; ");
			}
		}
		return goles;
	}

	/**
	 * 
	 * @param goles
	 */
	public void setGoles(StringBuffer goles) {
		this.goles = goles;
	}

	/**
	 * 
	 * @return
	 */
	public Amonestacion getAmonestacion() {
		return amonestacion;
	}

	/**
	 * 
	 * @param amonestacion
	 */
	public void setAmonestacion(Amonestacion amonestacion) {
		this.amonestacion = amonestacion;
	}

	/**
	 * 
	 * @return
	 */
	public SegJugador getLesionado() {
		return lesionado;
	}

	/**
	 * 
	 * @param lesionado
	 */
	public void setLesionado(SegJugador lesionado) {
		this.lesionado = lesionado;
	}

	/**
	 * 
	 * @return
	 */
	public StringBuffer getTarjetas() {
		// comprobamos si hay amonestaciones o no
		if (tarjetas == null) {
			tarjetas = new StringBuffer();

			List<Amonestacion> amonestacionesPartido = new ArrayList<Amonestacion>();
			amonestacionesPartido.addAll(partido.getM_amonestaciones());
			Collections.sort(amonestacionesPartido);
			for (Amonestacion a : amonestacionesPartido) {
				// rellenamos incidencias
				if (a.getTipo() != null) {
					tarjetas.append(a.getPeriodo());
					tarjetas.append("ª parte, ");
					tarjetas.append("min ");
					tarjetas.append(a.getMin());
					tarjetas.append(". ");
					tarjetas.append(a.getTipo().getTipo());
					tarjetas.append(" a ");
					tarjetas.append(a.getJugador().getPartJugador()
							.getJugador().getNombre());
					tarjetas.append("; ");
				}
			}
		}
		return tarjetas;
	}

	/**
	 * 
	 * @param tarjetas
	 */
	public void setTarjetas(StringBuffer tarjetas) {
		this.tarjetas = tarjetas;
	}

	/**
	 * 
	 * @return
	 */
	public Penalty getPenalty() {
		return penalty;
	}

	/**
	 * 
	 * @param penalty
	 */
	public void setPenalty(Penalty penalty) {
		this.penalty = penalty;
	}

	/**
	 * 
	 * @return
	 */
	public String getEquipoInfractor() {
		return equipoInfractor;
	}

	/**
	 * 
	 * @param equipoInfractor
	 */
	public void setEquipoInfractor(String equipoInfractor) {
		this.equipoInfractor = equipoInfractor;
	}

	/**
	 * 
	 * @return
	 */
	public List<SegJugador> getInfractores() {
		return infractores;
	}

	/**
	 * 
	 * @param infractores
	 */
	public void setInfractores(List<SegJugador> infractores) {
		this.infractores = infractores;
	}

	/**
	 * 
	 * @return
	 */
	public List<SegJugador> getLanzadores() {
		return lanzadores;
	}

	/**
	 * 
	 * @param lanzadores
	 */
	public void setLanzadores(List<SegJugador> lanzadores) {
		this.lanzadores = lanzadores;
	}

	/**
	 * 
	 * @return
	 */
	public List<SegJugador> getJugadores() {
		return jugadores;
	}

	/**
	 * 
	 * @param jugadores
	 */
	public void setJugadores(List<SegJugador> jugadores) {
		this.jugadores = jugadores;
	}

	/**
	 * 
	 * @return
	 */
	public List<TipoGolDic> getTiposGol() {
		return tiposGol;
	}

	/**
	 * 
	 * @param tiposGol
	 */
	public void setTiposGol(List<TipoGolDic> tiposGol) {
		this.tiposGol = tiposGol;
	}

	/**
	 * 
	 * @return
	 */
	public List<TipoAmonestacionDic> getTiposAmonestacion() {
		return tiposAmonestacion;
	}

	/**
	 * 
	 * @param tiposAmonestacion
	 */
	public void setTiposAmonestacion(List<TipoAmonestacionDic> tiposAmonestacion) {
		this.tiposAmonestacion = tiposAmonestacion;
	}
}
